package com.linran.quartz.demo1;

import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 定时器管理类
 * @auther lin
 * @date 2020-04-20 18:23
 */
@Slf4j
@Component
public class QuartzManager {
    private static final String JOB_TASK = "TASK_";

    @Autowired
    private Scheduler scheduler;

    /**
     * 动态添加job
     * @param quartzJob
     */
    public void addJob(QuartzJob quartzJob){
        try {
            //创建job
            //实际只能创建事先定义好的ExecutionJob任务，只是动态配置调度计划
            JobDetail job = JobBuilder.newJob(ExecutionJob.class)
                    //可以通过JobKey检索出该job
                    .withIdentity(JOB_TASK + quartzJob.getJobId())
                    .build();

            //创建trigger
            CronTrigger trigger = TriggerBuilder.newTrigger()
                    //可以通过TriggerKey检索出该trigger
                    .withIdentity(JOB_TASK + quartzJob.getJobId())
                    .startNow()
                    .withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCornExpre()))
                    .build();

            //将job信息传入jobDataMap中
            trigger.getJobDataMap().put(QuartzJob.JOB_KEY,quartzJob);

            //重置启动时间(不是很明白)
            ((CronTriggerImpl)trigger).setStartTime(new Date());

            //交由schedule调度(job也是在schedule内部通过QuartzJobFactory注入进spring容器中)
            scheduler.scheduleJob(job,trigger);

            //暂停任务
            if (quartzJob.isPause()){
                pause(quartzJob);
            }
        } catch (SchedulerException e) {
            log.error("创建定时任务失败",e);
        }
    }

    /**
     * 修改任务cron
     * @param quartzJob
     */
    public void updateJobCron(QuartzJob quartzJob){
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(JOB_TASK + quartzJob.getJobId());
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

            //如果不存在则创建job
            if (trigger == null){
                addJob(quartzJob);
                trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            }

            //更新trigger
            trigger = trigger.getTriggerBuilder()
                    .withIdentity(triggerKey)
                    .withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getCornExpre())).build();

            //重置启动时间
            ((CronTriggerImpl)trigger).setStartTime(new Date());
            trigger.getJobDataMap().put(QuartzJob.JOB_KEY,quartzJob);

            scheduler.rescheduleJob(triggerKey,trigger);
            //暂停任务
            if (quartzJob.isPause()){
                pause(quartzJob);
            }
        } catch (SchedulerException e) {
            log.error("更新定时任务失败",e);
        }
    }

    /**
     * 删除一个job
     */
    public void deleteJob(QuartzJob quartzJob){
        try {
            JobKey jobKey = JobKey.jobKey(JOB_TASK + quartzJob.getJobId());
            scheduler.pauseJob(jobKey);
            scheduler.deleteJob(jobKey);
        } catch (SchedulerException e) {
            log.error("删除任务失败",e);
        }
    }

    /**
     * 恢复一个job
     * @param quartzJob
     */
    public void resume(QuartzJob quartzJob){
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(JOB_TASK + quartzJob.getJobId());
            Trigger trigger = scheduler.getTrigger(triggerKey);

            //如果trigger为空，则新建job
            if (trigger == null){
                addJob(quartzJob);
            }

            JobKey jobKey = JobKey.jobKey(JOB_TASK + quartzJob.getJobId());
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            log.error("激活定时任务失败",e);
        }
    }

    /**
     * 立即执行job
     */
    public void runJobNow(QuartzJob quartzJob){
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(JOB_TASK + quartzJob.getJobId());
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if (trigger == null){
                addJob(quartzJob);
            }
            JobDataMap dataMap = new JobDataMap();
            dataMap.put(QuartzJob.JOB_KEY,quartzJob);
            JobKey jobKey = JobKey.jobKey(JOB_TASK + quartzJob.getJobId());
            scheduler.triggerJob(jobKey,dataMap);
        } catch (SchedulerException e) {
            log.error("定时任务执行失败",e);
        }
    }

    /**
     * 暂停任务
     */
    public void pause(QuartzJob quartzJob){
        try {
            //withIdentify
            JobKey jobKey = JobKey.jobKey(JOB_TASK + quartzJob.getJobId());
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            log.error("暂停任务失败!", e);
        }
    }
}
